/*
 * Node.h
 *
 * Author: ansuz
 * Verantwortlicher: alle
 *
 * Diese Klasse stellt das grundlegende Gerüst für einen Knoten dar.
 * Sie muss abgeleitet werden, um benutzt werden zu können.
 */


#ifndef NODE_H_
#define NODE_H_

#include <rodos.h>
#include "resumer.h"
#include "worker-monitor-topics.h"

/*TODO: Vielleicht sollten wir diese Klasse abstrakter gestalten, indem wir auch
 * 		die Nachrichtenbehandlung (wHandleMessages() und mHandleMessages()) als abstrakte
 * 		Funktionen setzen und diese von der erbenden Klasse implementieren lassen.
 * 		Außerdem könnten wir beide zu einer Funktion zusammenfassen und dieser dann einen
 * 		Parameter übergeben, aus dem die Funktion (wenn gewünscht) auf den Arbeitsmodus des
 * 		Knoten schließen kann.
 *
 * 		Einer der Vorteile, sie so abstrakt zu machen wäre, dass wir auch Knoten erstellen
 * 		könnten, die sich nicht in das Worker/Monitor-Schema einordnen lassen.
 */


class Node : public Thread {
private:
	TTime workerTimeOut;
	long nodeID;
	operationMode oMode;
	StatusData statusData;
	Fifo<WMMessage,32> messageBuffer;
	Subscriber messageSubscriber;
	Fifo<long,32> workerAliveBuffer;
	Subscriber workerAliveSubscriber;
	bool sendStatusData;
	long long timeLastPublish;
	unsigned long timePublishInterval;



	/**
	 * Flushes the buffers so they are empty.
	 */
	void flushBuffers();

	/**
	 * Handles messages from the EGSE.
	 * @return true if this node a worker, false otherwise
	 */
	bool EGSEHandleMessages(WMMessage topicInput,bool isWorker);

	/**
	 * Handles messages for the worker.
	 * @return true if this node is still a worker, false otherwise
	 */
	bool wHandleMessages();

	/**
	 * Handles messages for the monitor.
	 * @return true if this node has become a worker, false otherwise
	 */
	bool mHandleMessages();

	/**
	 * Send statusinfo to EGSE. if interval is 0 then send only one time.
	 */

	void StartSendStatusInfo(unsigned long interval);

	void StopSendStatusInfo();

	void publishStatusData(StatusData* data);

public:

	///Initializes the member fields.
	Node(TTime workingTime);

	//Should never be called
	virtual ~Node();

	/**
	 * Initializes the node.
	 */
	void init();

	/**
	 * Handles the worker/monitor execution.
	 */
	void run();

	/**
	 * Does the work when this node is the worker.
	 */
	virtual StatusData* work() = 0;
};

static LinkinterfaceUDP linkToNodes;
static Gateway topicGateway(&linkToNodes);
static Resumer gatewayResumer;

#endif /* NODE_H_ */
